package JasPerl::PageContext::PageWriter;

use strict;
use warnings;

use parent qw(JasPerl::JspWriter);

use JasPerl::Util::Exceptions;

my $DEFAULT_BUFFER_SIZE = 16384;

sub new {
    my ($class, $response, $buffer_size, $auto_flush) = @_;
    $buffer_size = $DEFAULT_BUFFER_SIZE if $buffer_size < 0;

    return bless {
        buffer => '',
        response => $response,
        buffer_size => $buffer_size,
        auto_flush => $auto_flush,
    }, $class;
}

sub get_buffer_size {
    return $_[0]->{buffer_size};
}

sub get_remaining {
    my $self = shift;
    return 0 unless exists $self->{buffer};
    return $self->{buffer_size} - length $self->{buffer};
}

sub is_auto_flush {
    return $_[0]->{auto_flush};
}

sub clear {
    my $self = shift;
    JasPerl::Util::IOException->throw("cannot clear flushed buffer")
        unless exists $self->{buffer};
    $self->{buffer} = '';
}

sub flush {
    my $self = shift;

    if (exists $self->{buffer}) {
        $self->{out} = $self->{response}->get_writer();
        $self->{out}->write($self->{buffer});
        delete $self->{buffer};
    }

    $self->{out}->flush() or JasPerl::Util::IOException->throw($!);
}

sub write {
    my ($self, $buf, $len, $off) = @_;
    $len = length $buf unless defined $len;

    if (exists $self->{buffer}) {
        if ($len <= $self->get_remaining()) {
            $self->{buffer} .= substr($buf, $off || 0, $len);
            return;
        } elsif ($self->is_auto_flush()) {
            $self->flush();
        } else {
            JasPerl::Util::IOException->throw('buffer overflow');
        }
    }

    $self->{out}->write($buf, $len, $off || 0)
        or JasPerl::Util::IOException->throw($!);
}

1;
